#include "Keyboard.h"
extern struct Motor_Ctrl MC;
extern char keyChar;

#define KEY_IS_PULLUP 1

#define Rowx_Port(x)			Row##x##_GPIO_Port
#define Rowx_Pin(x)				Row##x##_Pin
#define Read_Rowx_Pin(x)			HAL_GPIO_ReadPin(Rowx_Port(x), Rowx_Pin(x))
#define Write_Rowx_Pin(x,state)		HAL_GPIO_WritePin(Rowx_Port(x), Rowx_Pin(x), state)

#define Columnx_Port(x)			Column##x##_GPIO_Port
#define Columnx_Pin(x)			Column##x##_Pin
#define Read_Columnx_Pin(x)			HAL_GPIO_ReadPin(Columnx_Port(x), Columnx_Pin(x))
#define Write_Columnx_Pin(x,state)	HAL_GPIO_WritePin(Columnx_Port(x), Columnx_Pin(x), state)

#define GPIO_Init(Port,Pinx) do{GPIO_InitStruct.Pin = Pinx;HAL_GPIO_Init(Port, &GPIO_InitStruct);}while(0)
#define Bitx(x) (0x01<<x)
#if 0
const char KeyChar[]={	'1','2','3','A',\
						'4','5','6','B',\
						'7','8','9','C',\
						'*','0','#','D' };
#elif 0
const char KeyChar[]={	'D','C','B','A',\
						'#','9','6','3',\
						'0','8','5','2',\
						'*','7','4','1' };

#elif 0
const char KeyChar[]={	'D','#','0','*',\
						'C','9','8','7',\
						'B','6','5','4',\
						'A','3','2','1' };
#elif 0
const char KeyChar[]={	'1','4','7','*',\
						'2','5','8','0',\
						'3','6','9','#',\
						'A','B','C','D' };
#else
const char KeyChar[]={	'u','7','8','9',\
						'd','4','5','6',\
						'l','1','2','3',\
						'r','D','0','E' };		
#endif	


/*Flip left and right
[0-1-2-3] or [3-2-1-0]*/
#define C1 0
#define C2 1
#define C3 2
#define C4 3
/*Flip vertical
[0-1-2-3] or [3-2-1-0]*/
#define R1 3
#define R2 2
#define R3 1
#define R4 0
void Keyboard_Row_Out()
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
/*Configure GPIO pins : Public Part*/
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

/*Configure GPIO pins : Separate Part*/
  GPIO_Init(Row0_GPIO_Port,Row0_Pin);
  GPIO_Init(Row1_GPIO_Port,Row1_Pin);
  GPIO_Init(Row2_GPIO_Port,Row2_Pin);
  GPIO_Init(Row3_GPIO_Port,Row3_Pin);
  
/* Set GPIO pins */
  Write_Rowx_Pin(0,GPIO_PIN_SET);
  Write_Rowx_Pin(1,GPIO_PIN_SET);
  Write_Rowx_Pin(2,GPIO_PIN_SET);
  Write_Rowx_Pin(3,GPIO_PIN_SET);
  
}
void Keyboard_Row_In()
{
/* Set GPIO pins */
  Write_Rowx_Pin(0,GPIO_PIN_RESET);
  Write_Rowx_Pin(1,GPIO_PIN_RESET);
  Write_Rowx_Pin(2,GPIO_PIN_RESET);
  Write_Rowx_Pin(3,GPIO_PIN_RESET);
	
  GPIO_InitTypeDef GPIO_InitStruct = {0};
/*Configure GPIO pins : Public Part */
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  
/*Configure GPIO pins : Separate Part*/
  GPIO_Init(Row0_GPIO_Port,Row0_Pin);
  GPIO_Init(Row1_GPIO_Port,Row1_Pin);
  GPIO_Init(Row2_GPIO_Port,Row2_Pin);
  GPIO_Init(Row3_GPIO_Port,Row3_Pin);
}
void Keyboard_Column_Out()
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
/*Configure GPIO pins : Public Part*/
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

/*Configure GPIO pins : Separate Part*/
  GPIO_Init(Column0_GPIO_Port,Column0_Pin);
  GPIO_Init(Column1_GPIO_Port,Column1_Pin);
  GPIO_Init(Column2_GPIO_Port,Column2_Pin);
  GPIO_Init(Column3_GPIO_Port,Column3_Pin);
  
/* Set GPIO pins */
  Write_Columnx_Pin(0,GPIO_PIN_SET);
  Write_Columnx_Pin(1,GPIO_PIN_SET);
  Write_Columnx_Pin(2,GPIO_PIN_SET);
  Write_Columnx_Pin(3,GPIO_PIN_SET);
}
void Keyboard_Column_In()
{
/* Set GPIO pins */
  Write_Columnx_Pin(0,GPIO_PIN_RESET);
  Write_Columnx_Pin(1,GPIO_PIN_RESET);
  Write_Columnx_Pin(2,GPIO_PIN_RESET);
  Write_Columnx_Pin(3,GPIO_PIN_RESET);
	
  GPIO_InitTypeDef GPIO_InitStruct = {0};
/*Configure GPIO pins : Public Part */
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  
/*Configure GPIO pins : Separate Part*/
  GPIO_Init(Column0_GPIO_Port,Column0_Pin);
  GPIO_Init(Column1_GPIO_Port,Column1_Pin);
  GPIO_Init(Column2_GPIO_Port,Column2_Pin);
  GPIO_Init(Column3_GPIO_Port,Column3_Pin);
}

/**
  * @brief  Get the value entered by the keyboard
  * @param  None
  * @retval Input Value
  */
uint16_t Get_Keyborad(void)
{
	uint16_t Input=0;
	uint16_t Row=0;
	uint16_t Column=0;
	
	Keyboard_Column_Out();
	Keyboard_Row_In();
	Row = ((Read_Rowx_Pin(0)<<R1) | (Read_Rowx_Pin(1)<<R2) | (Read_Rowx_Pin(2)<<R3) | (Read_Rowx_Pin(3)<<R4));

	
	Keyboard_Row_Out();
#if KEY_IS_PULLUP == 1
		Write_Rowx_Pin(0,GPIO_PIN_RESET);
		Write_Rowx_Pin(1,GPIO_PIN_RESET);
		Write_Rowx_Pin(2,GPIO_PIN_RESET);
		Write_Rowx_Pin(3,GPIO_PIN_RESET);	
#endif
	Keyboard_Column_In();
	
#if KEY_IS_PULLUP == 1
	Column = 0x0F&~((Read_Columnx_Pin(0)<<C1) | (Read_Columnx_Pin(1)<<C2) | (Read_Columnx_Pin(2)<<C3) | (Read_Columnx_Pin(3)<<C4));
#else
	Column = ((Read_Columnx_Pin(0)<<0) | (Read_Columnx_Pin(1)<<1) | (Read_Columnx_Pin(2)<<2) | (Read_Columnx_Pin(3)<<3));
#endif

//	UARTx_Printf(&huart1, "Row=%X,Column=%X,C2:%d,C1:%d\n\r", Row, Column,Read_Columnx_Pin(1),Read_Columnx_Pin(0));
#if R_C_EXCHANGE == 1

#endif
	if(Row & Bitx(3))
	{
		if(Column & Bitx(3))
		{
			Input |= Bitx(0);
		}
		if(Column & Bitx(2))
		{
			Input |= Bitx(1);
		}
		if(Column & Bitx(1))
		{
			Input |= Bitx(2);
		}
		if(Column & Bitx(0))
		{
			Input |= Bitx(3);
		}
	}
	if(Row & Bitx(2))
	{
		if(Column & Bitx(3))
		{
			Input |= Bitx(4);
		}
		if(Column & Bitx(2))
		{
			Input |= Bitx(5);
		}
		if(Column & Bitx(1))
		{
			Input |= Bitx(6);
		}
		if(Column & Bitx(0))
		{
			Input |= Bitx(7);
		}
	}
	if(Row & Bitx(1))
	{
		if(Column & Bitx(3))
		{
			Input |= Bitx(8);
		}
		if(Column & Bitx(2))
		{
			Input |= Bitx(9);
		}
		if(Column & Bitx(1))
		{
			Input |= Bitx(10);
		}
		if(Column & Bitx(0))
		{
			Input |= Bitx(11);
		}
	}
	if(Row & Bitx(0))
	{
		if(Column & Bitx(3))
		{
			Input |= Bitx(12);
		}
		if(Column & Bitx(2))
		{
			Input |= Bitx(13);
		}
		if(Column & Bitx(1))
		{
			Input |= Bitx(14);
		}
		if(Column & Bitx(0))
		{
			Input |= Bitx(15);
		}
	}
//		UARTx_Printf(&huart1,"Input=%X\n\r",Input);
	return Input;
}

/**
  * @brief  Scan key status and it have max trigger times
  * @param  status  :Key input status
			pSwitch :iSwitch Struct handle
  * @notes  This function requires 1ms clock
  * @retval [0]No trigger,[1]Trigger
  */
char Keyboard_Scan(uint16_t input)
{
	char str;
	if(input)
	{
	switch(input)
		{
			case 0x8000:
			{
				str = KeyChar[0];//"up"
			}break;
			case 0x4000:
			{
				str = KeyChar[1];
			}break;
			case 0x2000:
			{
				str = KeyChar[2];
			}break;
			case 0x1000:
			{
				str = KeyChar[3];
			}break;
			case 0x800:
			{
				str = KeyChar[4];//"down"
			}break;
			case 0x400:
			{
				str = KeyChar[5];
			}break;
			case 0x200:
			{
				str = KeyChar[6];
			}break;
			case 0x100:
			{
				str = KeyChar[7];
			}break;
			case 0x80:
			{
				str = KeyChar[8];//"left"
			}break;
			case 0x40:
			{
				str = KeyChar[9];//"1"
			}break;
			case 0x20:
			{
				str = KeyChar[10];//"2"
			}break;
			case 0x10:
			{
				str = KeyChar[11];//"3"
			}break;
			case 0x8:
			{
				str = KeyChar[12];//"right"
			}break;
			case 0x4:
			{
				str = KeyChar[13];
			}break;
			case 0x2:
			{
				str = KeyChar[14];
			}break;
			case 0x1:
			{
				str = KeyChar[15];//"E"
			}break;
		}
//		UARTx_Printf(&huart1,&str);
	}
	return keyChar = str;
	
}






